﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System;
using System.Runtime.Serialization;
using System.ComponentModel;

namespace BrainTechLLC
{
#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
    [Serializable]
    public class DirectionFloat : Vector4BaseFloat, IVector4Float, IDirectionFloat, IQuickCopy
    {
        public IDirectionFloat DirectionVector { get { return this; } set { Set(value); } }
        public DirectionFloat(float x, float y, float z, float w) : base(x, y, z, w) { }
        public DirectionFloat(IDirectionFloat dir) : base(dir as Vector4BaseFloat) { }
        public DirectionFloat(float x, float y, float z) : base(x, y, z) { }
        public DirectionFloat() { }

        public virtual object Copy() { return new DirectionFloat(X, Y, Z, W); }

        [NonSerialized]
        public static readonly DirectionFloat[] VectorsForDirections = new DirectionFloat[]
        {
            new DirectionFloat(0, 0, 0),		// None
            new DirectionFloat(0, -1, 0),	    // N
            new DirectionFloat(1, 0, 0),		// E
            new DirectionFloat(-1, 0, 0),	    // W
            new DirectionFloat(0, 1, 0),		// S
            new DirectionFloat(-1, -1, 0),	    // NW
            new DirectionFloat(1, -1, 0),	    // NE
            new DirectionFloat(1, 1, 0),		// SE
            new DirectionFloat(-1, 1, 0)		// SW
        };

        public GeneralDirection CardinalDirection
        {
            get
            {
                if (X > 0)
                {
                    return
                         (Y > 0) ? GeneralDirection.SE :
                         (Y < 0) ? GeneralDirection.NE :
                         GeneralDirection.E;
                }
                else if (X < 0)
                {
                    return
                         (Y > 0) ? GeneralDirection.SW :
                         (Y < 0) ? GeneralDirection.NW :
                         GeneralDirection.W;
                }
                else
                {
                    // X == 0
                    return
                         (Y > 0) ? GeneralDirection.S :
                         (Y < 0) ? GeneralDirection.N :
                         GeneralDirection.None;
                }
            }
        }

        /// <summary>
        /// Gets the N/S or E/W symmetric vector, as specified by the symmetry parameter
        /// </summary>		
        public IDirectionFloat GetSymmetric(Symmetry symmetry)
        {
            DirectionFloat result = this.Copy() as DirectionFloat;

            if ((symmetry & Symmetry.XAxis) != 0)
                result.X = -result.X;

            if ((symmetry & Symmetry.YAxis) != 0)
                result.Y = -result.Y;

            if ((symmetry & Symmetry.ZAxis) != 0)
                result.Z = -result.Z;

            return result;
        }
    }
}
